home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / lkbackup.zip / ntdirent.c < prev    next >
C/C++ Source or Header  |  1993-09-25  |  5KB  |  222 lines

  1. /* Unix compatible directory functions for Windows NT
  2.  * Patched together code from the NT port of Perl done by 
  3.  * Clark Williams of Intergraph Corp. with the header file
  4.  * from the Microsoft Windows NT SDK Posix subsystem.
  5. */
  6.  
  7. /*
  8.  *  Portions of this code Copyright (c) 1993, Intergraph Corporation
  9.  */
  10.  
  11. /*
  12.  * $Log: $
  13.  */
  14.  
  15. static char ntdirver[] = "$Id: ntdir.c,v 1.3 1993/09/16 01:10:14 ESullivan Exp ESullivan $";
  16. #include <fcntl.h>
  17. #include <process.h>
  18. #include <sys/stat.h>
  19. #include <assert.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <malloc.h>
  24. #include <windows.h>
  25. #include "ntdirent.h"
  26. #include "ntmem.h"
  27.  
  28. static void fatal( char * );
  29. //
  30. // File names are converted to lowercase if the
  31. // CONVERT_TO_LOWER_CASE variable is defined.
  32. //
  33.  
  34. #define CONVERT_TO_LOWER_CASE
  35.  
  36. #define PATHLEN 1024
  37.  
  38. //
  39. // The idea here is to read all the directory names into a string table
  40. // (separated by nulls) and when one of the other dir functions is called
  41. // return the pointer to the current file name. 
  42. //
  43.  
  44. DIR *opendir(const char *filename)
  45. {
  46.     DIR            *p;
  47.     long            len;
  48.     long            idx;
  49.     char            scannamespc[PATHLEN];
  50.     char               *scanname = scannamespc;
  51.     struct stat        sbuf;
  52.     WIN32_FIND_DATA FindData;
  53.     HANDLE          fh;
  54.  
  55.     //
  56.     // check to see if we\'ve got a directory
  57.     //
  58.  
  59.     if (stat (filename, &sbuf) < 0 ||
  60.     sbuf.st_mode & _S_IFDIR == 0) {
  61.     return NULL;
  62.     }
  63.  
  64.     //
  65.     // Get us a DIR structure
  66.     //
  67.  
  68.     Newz (1501, p, 1, DIR);
  69.     if (p == NULL)
  70.     return NULL;
  71.     
  72.     //
  73.     // Create the search pattern
  74.     //
  75.  
  76.     strcpy(scanname, filename);
  77.  
  78.     if (strchr("/\\", *(scanname + strlen(scanname) - 1)) == NULL)
  79.     strcat(scanname, "/*");
  80.     else
  81.     strcat(scanname, "*");
  82.  
  83.     //
  84.     // do the FindFirstFile call
  85.     //
  86.  
  87.     fh = FindFirstFile (scanname, &FindData);
  88.     if (fh == INVALID_HANDLE_VALUE) {
  89.     return NULL;
  90.     }
  91.  
  92.     //
  93.     // now allocate the first part of the string table for the
  94.     // filenames that we find.
  95.     //
  96.  
  97.     idx = strlen(FindData.cFileName)+1;
  98.     New (1502, p->start, idx, char);
  99.     if (p->start == NULL) {
  100.     fatal ("opendir: malloc failed!\n");
  101.     }
  102.     strcpy (p->start, FindData.cFileName);
  103.     p->nfiles++;
  104.     
  105.     //
  106.     // loop finding all the files that match the wildcard
  107.     // (which should be all of them in this directory!).
  108.     // the variable idx should point one past the null terminator
  109.     // of the previous string found.
  110.     //
  111.     while (FindNextFile(fh, &FindData)) {
  112.     len = strlen (FindData.cFileName);
  113.  
  114.     //
  115.     // bump the string table size by enough for the
  116.     // new name and it's null terminator 
  117.     //
  118.  
  119.     Renew (p->start, idx+len+1, char);
  120.     if (p->start == NULL) {
  121.         fatal ("opendir: malloc failed!\n");
  122.     }
  123.     strcpy(&p->start[idx], FindData.cFileName);
  124.     p->nfiles++;
  125.     idx += len+1;
  126.     }
  127.     FindClose(fh);
  128.     p->size = idx;
  129.     p->curr = p->start;
  130.     return p;
  131. }
  132.  
  133.  
  134. //
  135. // Readdir just returns the current string pointer and bumps the
  136. // string pointer to the next entry.
  137. //
  138.  
  139. struct dirent *readdir(DIR *dirp)
  140. {
  141.     int         len;
  142.     static int  dummy = 0;
  143.  
  144.     if (dirp->curr) {
  145.  
  146.     //
  147.     // first set up the structure to return
  148.     //
  149.  
  150.     len = strlen(dirp->curr);
  151.     strcpy(dirp->dirstr.d_name, dirp->curr);
  152.     dirp->dirstr.d_namlen = len;
  153.  
  154.     //
  155.     // Fake inode
  156.     //
  157.     dirp->dirstr.d_ino = dummy++;
  158.  
  159.     //
  160.     // Now set up for the next call to readdir
  161.     //
  162.  
  163.     dirp->curr += len + 1;
  164.     if (dirp->curr >= (dirp->start + dirp->size)) {
  165.         dirp->curr = NULL;
  166.     }
  167.  
  168.     return &(dirp->dirstr);
  169.  
  170.     } else
  171.     return NULL;
  172. }
  173.  
  174. //
  175. // Telldir returns the current string pointer position
  176. //
  177.  
  178. long telldir(DIR *dirp)
  179. {
  180.     return (long) dirp->curr;    /* ouch! pointer to long cast */
  181. }
  182.  
  183. //
  184. // Seekdir moves the string pointer to a previously saved position
  185. // (Saved by telldir).
  186.  
  187. void seekdir(DIR *dirp, long loc)
  188. {
  189.     dirp->curr = (char *) loc;    /* ouch! long to pointer cast */
  190. }
  191.  
  192. //
  193. // Rewinddir resets the string pointer to the start
  194. //
  195.  
  196. void  rewinddir(DIR *dirp)
  197. {
  198.     dirp->curr = dirp->start;
  199. }
  200.  
  201. //
  202. // This just free\'s the memory allocated by opendir
  203. //
  204.  
  205. void  closedir(DIR *dirp)
  206. {
  207.     Safefree(dirp->start);
  208.     Safefree(dirp);
  209. }
  210.  
  211. /* Print an error message containing the string TEXT, then exit.  */
  212.  
  213. static void fatal(char *string)
  214. {
  215.     fprintf(stderr, "%s\n", string);
  216.     exit(2);
  217. }
  218.  
  219.  
  220.  
  221.  
  222.